package Day_0208.Redis;

/**
 * @author zxc
 * @date 2023/02/08 12:06
 **/
public class Redis_Expiration_Policies {
    public static void main(String[] args) {
        /**
         * Redis的过期策略 && 内存淘汰机制
         * ===》
         * 1.redis采用的是定期删除+惰性删除策略。
         *
         * 2.为什么不用定时删除策略?
         * （1）定时删除,用一个定时器来负责监视key,过期则自动删除。
         * （2）虽然内存及时释放，但是十分消耗CPU资源。
         * （3）在大并发请求下，CPU要将时间应用在处理请求，而不是删除key,因此没有采用这一策略
         * ===》
         * 即，会为每一个key设置一个定时器，过期自动删除;
         * 在高并发情况下，会导致占用大量CPU资源;
         *
         * 3.定期删除+惰性删除是如何工作的呢?
         * （1）定期删除，redis默认每个100ms检查，是否有过期的key,有过期key则删除。
         *  需要说明的是，redis不是每个100ms将所有的key检查一次，而是随机抽取进行检查;(如果每隔100ms,全部key进行检查，redis岂不是卡死)。
         *  ===》因此，如果只采用定期删除策略，会导致很多key到时间没有删除。
         * （2）惰性删除派上用场 :
         *  也就是说在你获取某个key的时候，redis会检查一下，这个key如果设置了过期时间那么是否过期了？
         *  如果过期了此时就会删除。
         *
         * 4.采用定期删除+惰性删除所带来的问题
         * （1）如果定期删除没删除key。
         * （2）然后你也没即时去请求key，也就是说惰性删除也没生效。
         * ===》redis的内存会越来越高，直至Redis崩溃。
         *
         * 5.采用合适的内存淘汰机制。
         * （1）在redis.conf中有一行配置
         * maxmemory-policy volatile-lru
         *
         * （2）该配置就是配内存淘汰策略 ：
         * volatile-lru：从已设置过期时间的数据集（server.db[i].expires）中挑选最近最少使用的数据淘汰
         * volatile-ttl：从已设置过期时间的数据集（server.db[i].expires）中挑选将要过期的数据淘汰
         * volatile-random：从已设置过期时间的数据集（server.db[i].expires）中任意选择数据淘汰
         * allkeys-lru：从数据集（server.db[i].dict）中挑选最近最少使用的数据淘汰
         * allkeys-random：从数据集（server.db[i].dict）中任意选择数据淘汰
         * no-enviction（驱逐）：禁止驱逐数据，新写入操作会报错
         *
         * ps：如果没有设置 expire（过期时间） 的key, 不满足先决条件(prerequisites);
         * 那么 volatile-lru, volatilerandom 和 volatile-ttl 策略的行为, 和 noeviction(不删除) 基本上一致。
         *
         * ===》
         * 总结 ：
         * （1）定期删除 ：Redis每间隔100ms，随机抽取一部分key进行检查，若是有过期key，则将其删除;
         * （2）惰性删除 ：当获取某个key时，会去检查其是否过期;
         * ===》 若是有部分key定期删除未将其删除 && 这些key长时间不被访问，会导致Redis中内存过大，导致Redis崩溃;
         * （3）内存淘汰机制
         *
         */
    }
}
